package br.usp.icmc.client.controladores;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;

import br.usp.icmc.client.dao.AdminDAO;
import br.usp.icmc.client.dao.ClientDAO;
import br.usp.icmc.client.dao.ProviderDAO;
import br.usp.icmc.client.entidades.Admin;
import br.usp.icmc.client.entidades.Client;
import br.usp.icmc.client.entidades.Provider;
import br.usp.icmc.client.exception.LoginException;
import br.usp.icmc.client.main.Console;
import br.usp.icmc.client.util.Login;

/********************************************************************************
 * <b> <br> Projeto: Aplicativo Cliente <br><b>
 * 
 * Classe de controle do Login
 * 
 * @author felipe
 * 
 *******************************************************************************/
public class ControllerLogin {
	
	// Constantes do tipo de login
	private static int NONE = 0;
	private static int CLIENT = 1;
	private static int PROVIDER = 2;
	private static int ADMIN = 3;
	private static int ERROR = 4;
	
	private int loginType;
	private ClientDAO clientDAO;
	private ProviderDAO providerDAO;
	private AdminDAO adminDAO;
	
	private Client client;
	private Provider provider;
	private Admin admin;
	List list;
	Login objLogin;
	
	private String log;
	
	/*************************************************
	 * Construtor padrão da entidade ControllerLogin
	 ************************************************/
	public ControllerLogin(){
		clientDAO = new ClientDAO();
		providerDAO = new ProviderDAO();
		adminDAO= new AdminDAO();
		loginType = NONE;
		objLogin = new Login();
	}
	
	/***********************************************************************************
	 * 
	 * Verifica se o login existe
	 * 
	 * @param email
	 * 				Email do login
	 * @param password
	 * 				Senha do login
	 * @throws LoginException
	 **********************************************************************************/
	public void verifyLogin(String email, String password) {
		
		list = adminDAO.login(email, password);
		
		if(!list.isEmpty()){
			loginType = ADMIN;
			return;
		}	
		
		list = providerDAO.login(email, password);
		
		if(!list.isEmpty()){
			loginType = PROVIDER;
			return;
		}
		
		list = clientDAO.login(email, password);
		
		if(!list.isEmpty()){
			loginType = CLIENT;
			return;
		}
		
		loginType = ERROR;
		
	}
	/**
	 * Verifica permissão
	 * @param email
	 */
	public void verifyPermissao(String email){
		list = adminDAO.admin(email);
		
		if(!list.isEmpty()){
			loginType = ADMIN;
			return;
		}	
		
		list = providerDAO.provedor(email);
		
		if(!list.isEmpty()){
			loginType = PROVIDER;
			return;
		}
		
		list = clientDAO.cliente(email);
		
		if(!list.isEmpty()){
			loginType = CLIENT;
			return;
		}
		
		loginType = ERROR;
	}
	
	
	/**
	 * Verifica se o usuário está no sistema, sem se preocupar com o nível de autorização
	 * 
	 * @param email
	 * @param password
	 */
	public void verifyLoginSistema(String email, String password){
		list = clientDAO.login(email, password);
		
		if(!list.isEmpty()){
			loginType = CLIENT;
			return;
		}
		
		loginType = ERROR;
	}
	
	/**************************************************************
	 * Verifica se é provedor
	 * @return
	 * 	Retorna 'true' se for; 'false' caso contrário
	 *************************************************************/
	public boolean isProvider(){
		return (loginType == PROVIDER);
	}

	/**************************************************************
	 * Verifica se é cliente
	 * @return
	 * 	Retorna 'true' se for; 'false' caso contrário
	 *************************************************************/
	public boolean isClient(){
		return (loginType == CLIENT);
	}
	
	/**************************************************************
	 * Verifica se é admin
	 * @return
	 * 	Retorna 'true' se for; 'false' caso contrário
	 *************************************************************/
	public boolean isAdmin(){
		return (loginType == ADMIN);
	}
	
	
	
	public boolean isError(){
		return (loginType == ERROR);
	}
	
	public void setLogin(Login login){
		objLogin = login;
	}
	
	public Login getLogin(){
		loadLogin();
		return objLogin;
	}
	
	
	public void loadLogin(){
		
		File arquivo = new File("rosLogin.txt");
		String aux = "/";
		
		if(arquivo.exists()){
			try {
				String[] login = new String[3];
				FileReader fr = new FileReader(arquivo);
				BufferedReader br = new BufferedReader(fr);
				
				while(br.ready()){
					
					String linha = br.readLine();
					
					String[] result = linha.split("\\s");
					
					for(int i = 0; i < result.length; i++){
						login[i] = result[i]; 
					}					
					objLogin.setLogin(login[0]);
					objLogin.setPassword(login[1]);
					objLogin.setPath(login[2]);
					
					verifyLogin(objLogin.getLogin(), objLogin.getPassword());
					setLogin(objLogin);
					
					br.close();
					fr.close();
					
					//System.out.println("To discover all available commands type rss help");
					//console.executarMenuInicial();
					
				}
				
			} catch (IOException e) {
				
			} 
			
		} else {
			
			try {
				Scanner scanner = new Scanner(System.in);
				
				System.out.println("Enter your Login: ");
				String user = scanner.next();
				System.out.println("Enter your Password: ");
				String senha = scanner.next();				
				System.out.println("Enter your ROS Workspace path: (e.g. /home/user/)");
				String path = scanner.next();
													
				verifyLogin(user, senha);
				
											
				objLogin.setLogin(user);
				objLogin.setPassword(senha);
				objLogin.setPath(path.concat(aux));
				
				while(!isAdmin() && !isProvider() && !isClient()){
					System.out.println("Login or Password Incorret");
					System.out.println("Enter your Login: ");
					user = scanner.next();
					System.out.println("Enter your Password: ");
					senha = scanner.next();		
					
					verifyLogin(user, senha);
					
					objLogin.setLogin(user);
					objLogin.setPassword(senha);
					objLogin.setPath(path.concat(aux));
				}
				
				setLogin(objLogin);
				
				arquivo.createNewFile();
				
				FileWriter fw = new FileWriter(arquivo);
				BufferedWriter bw = new BufferedWriter(fw);				
				
				bw.write(objLogin.getLogin()+" "+objLogin.getPassword()+" "+objLogin.getPath());
				
				
			    
				bw.close();
				fw.close();
				
				
			} catch (IOException e) {
				System.out.println("ERROR2!");
			}			
		}
		
		
		
	}
	
	
	public void carregarLogin() throws ClassNotFoundException{
		ObjectInputStream is;
		try {
			is = new ObjectInputStream(new FileInputStream("rosLogin"));
			objLogin = (Login) is.readObject();
			is.close();
			verifyLogin(objLogin.getLogin(), objLogin.getPassword());
			setLogin(objLogin);
		} catch (FileNotFoundException e) {
			Scanner scanner = new Scanner(System.in);
			
			System.out.println("Enter your Login: ");
			String login = scanner.next();
			System.out.println("Enter your Password: ");
			String senha = scanner.next();
												
			verifyLogin(login, senha);
			
			objLogin.setLogin(login);
			objLogin.setPassword(senha);
			
			while(!isAdmin() && !isProvider() && !isClient()){
				System.out.println("Login or Password Incorret");
				System.out.println("Enter your Login: ");
				login = scanner.next();
				System.out.println("Enter your Password: ");
				senha = scanner.next();		
				
				verifyLogin(login, senha);
				
				objLogin.setLogin(login);
				objLogin.setPassword(senha);
			}
			
			setLogin(objLogin);
		    ObjectOutputStream os;
			try {
				os = new ObjectOutputStream(new FileOutputStream("rosLogin"));
				os.writeObject(objLogin);
				os.close();
			} catch (FileNotFoundException e1) {
				System.out.println("Erro file not found");
			} catch (IOException e1) {
				System.out.println("Erro IO 1");
			}
						
		} catch (IOException e) {
			System.out.println("error IO 2");
		}
		
		
		
	}
	
	
}
